package regtest;

import java.util.Comparator;
import java.util.Date;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.junit.Assert;

public class TempTest {

    public static void main(String[] args) {
        System.out.println(new Date(1563503841929L));

        System.out.println(new Date(1565074867271L));

        String input = "[a-zA-Z0-9]";
        Pattern p = Pattern.compile(input);

        System.out.println(p.matcher("333333").find());

        System.out.println(p.matcher("*").find());
        System.out.println(p.pattern());

        TempTest t = new TempTest();
        t.execute();

        Consumer<Object> c = new Consumer() {
            @Override
            public void accept(Object o) {
                System.out.println(o);
            }
        };

        Consumer cFunctional = (o) -> {
            System.out.println(o);
        };

        consumerTest();
        functionTest();
        predicateTest();

        Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa");

        s.flatMap(n -> Stream.of(n.split(""))).forEach(System.out::println);

        Stream.of("test", "t1", "t2", "teeeee", "aaaa").map(n -> n.concat("^_^")).forEach(System.out::println);

        Stream<String> s2 = Stream.of("test", "t1", "t2", "teeeee", "aaaa");
        s2.map(n -> n.concat(".txt")).forEach(System.out::println);

        biFunctionTest();

    }

    public void execute() {
        Optional<String> maybeString = Optional.of("foo");
        String newString = maybeString.map(TempTest::runIfExist).orElse(runIfEmpty());
        System.out.println(newString);
    }

    private static String runIfExist(String str) {
        System.out.println("only run if optional is filled!");
        return str;
    }

    public String runIfEmpty() {
        System.out.println("only run if empty!");
        return "empty";
    }

    public static void consumerTest() {
        Consumer f = System.out::println;
        Consumer f2 = n -> System.out.println(n + "-F2");
        //执行完F后再执行F2的Accept方法
        f.andThen(f2).accept("test");

        //连续执行F的Accept方法
        f.andThen(f).andThen(f).andThen(f).accept("test1");
    }

    /**
     * Function测试
     */
    public static void functionTest() {
        Function<Integer, Integer> f = s -> s++;
        Function<Integer, Integer> g = s -> s * 2;

        /**
         * 下面表示在执行F时，先执行G，并且执行F时使用G的输出当作输入。
         * 相当于以下代码：
         * Integer a = g.apply(1);
         * System.out.println(f.apply(a));
         */
        System.out.println(f.compose(g).apply(1));

        /**
         * 表示执行F的Apply后使用其返回的值当作输入再执行G的Apply；
         * 相当于以下代码
         * Integer a = f.apply(1);
         * System.out.println(g.apply(a));
         */
        System.out.println(f.andThen(g).apply(1));

        /**
         * identity方法会返回一个不进行任何处理的Function，即输出与输入值相等；
         */
        System.out.println(Function.identity().apply("a"));
    }


    /**
     * Predicate测试
     */
    private static void predicateTest() {
        Predicate<String> p = o -> o.equals("test");
        Predicate<String> g = o -> o.startsWith("t");

        /**
         * negate: 用于对原来的Predicate做取反处理；
         * 如当调用p.test("test")为True时，调用p.negate().test("test")就会是False；
         */
        Assert.assertFalse(p.negate().test("test"));

        /**
         * and: 针对同一输入值，多个Predicate均返回True时返回True，否则返回False；
         */
        Assert.assertTrue(p.and(g).test("test"));

        /**
         * or: 针对同一输入值，多个Predicate只要有一个返回True则返回True，否则返回False
         */
        Assert.assertTrue(p.or(g).test("ta"));
    }

    private static void biFunctionTest() {
        BiFunction<Integer, Integer, String> biFunction = (num1, num2) -> "Result:" + (num1 + num2);
        System.out.println(biFunction.apply(20, 25));

        System.out.println("============BiFunction===========");
        BiPredicate<Integer, String> condition = (i, s) -> i > 20 && s.startsWith("R");
        System.out.println(condition.test(10, "Ram"));
        System.out.println(condition.test(30, "Shyam"));
        System.out.println(condition.test(30, "Ram"));

    }
}
